"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
require("./actions/sender-button.vue.cjs");
require("./actions/loading-button.vue.cjs");
require("./actions/speech-button.vue.cjs");
require("./actions/speech-loading-button.vue.cjs");
require("./actions/link-button.vue.cjs");
require("./upload.vue.cjs");
const Recorder = require("js-audio-recorder");
const antDesignVue = require("ant-design-vue");
const index = require("../../upload-file/index.cjs");
const lodashEs = require("lodash-es");
require("../../icons/index.cjs");
const senderButton_vue_vue_type_script_setup_true_lang = require("./actions/sender-button.vue2.cjs");
const loadingButton_vue_vue_type_script_setup_true_lang = require("./actions/loading-button.vue2.cjs");
const speechButton_vue_vue_type_script_setup_true_lang = require("./actions/speech-button.vue2.cjs");
const speechLoadingButton_vue_vue_type_script_setup_true_lang = require("./actions/speech-loading-button.vue2.cjs");
const linkButton_vue_vue_type_script_setup_true_lang = require("./actions/link-button.vue2.cjs");
const fileExcelIcon = require("../../icons/file-excel-icon.vue.cjs");
const filePptIcon = require("../../icons/file-ppt-icon.vue.cjs");
const filePdfIcon = require("../../icons/file-pdf-icon.vue.cjs");
const fileUnkownIcon = require("../../icons/file-unkown-icon.vue.cjs");
const fileMarkdownIcon = require("../../icons/file-markdown-icon.vue.cjs");
const fileTextIcon = require("../../icons/file-text-icon.vue.cjs");
const fileWordIcon = require("../../icons/file-word-icon.vue.cjs");
const fileZipIcon = require("../../icons/file-zip-icon.vue.cjs");
const closeCircleFilledIcon = require("../../icons/close-circle-filled-icon.vue.cjs");
const plusIcon = require("../../icons/plus-icon.vue.cjs");
const upload_vue_vue_type_script_setup_true_lang = require("./upload.vue2.cjs");
const _hoisted_1 = { class: "me-sender-header-inner" };
const _hoisted_2 = { class: "me-sender-image-box" };
const _hoisted_3 = {
  key: 0,
  class: "me-sender-image"
};
const _hoisted_4 = {
  key: 0,
  class: "percent"
};
const _hoisted_5 = {
  key: 1,
  class: "me-sender-file"
};
const _hoisted_6 = { class: "file-wrap" };
const _hoisted_7 = { class: "file-logo" };
const _hoisted_8 = { class: "file-content" };
const _hoisted_9 = { class: "file-name" };
const _hoisted_10 = { class: "file-size" };
const _hoisted_11 = {
  key: 0,
  class: "percent"
};
const _hoisted_12 = { class: "me-sender-image upload-btn" };
const _hoisted_13 = ["placeholder", "value", "rows"];
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  ...{
    name: "me-sender"
  },
  __name: "sender",
  props: /* @__PURE__ */ vue.mergeModels({
    placeholder: { default: "请输入内容" },
    rows: { default: 1 },
    value: {},
    loading: { type: Boolean },
    uploadProps: { default() {
      return {
        fileList: [],
        afterUpload() {
          return true;
        },
        beforeUpload() {
          return true;
        }
      };
    } },
    uploadEvents: { default() {
      return {};
    } },
    upload: { type: Boolean, default: false },
    speech: { default() {
      return {
        enabled: true,
        blobType: "wav",
        fieldName: "filedata"
      };
    } },
    expand: { default() {
      return {
        height: 200,
        enabled: true
      };
    } },
    isSpeeching: { type: Boolean, default: false },
    onChange: {}
  }, {
    "value": {
      default: ""
    },
    "valueModifiers": {},
    "loading": {
      default: false
    },
    "loadingModifiers": {},
    "isSpeeching": { type: Boolean },
    "isSpeechingModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["send", "cancel"], ["update:value", "update:loading", "update:isSpeeching"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const recorder = new Recorder({
      sampleBits: 16,
      sampleRate: 16e3,
      numChannels: 1
    });
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    let recognition = new SpeechRecognition();
    recognition.continuous = true;
    recognition.interimResults = true;
    recognition.lang = "zh-CN";
    const emits = __emit;
    const props = __props;
    let isComposing = false;
    const senderRef = vue.ref();
    const textareaRef = vue.ref();
    const senderContentRef = vue.ref();
    const headerRef = vue.ref();
    const inputContent = vue.useModel(__props, "value");
    const loading = vue.useModel(__props, "loading");
    const isFocus = vue.ref(false);
    const isSpeeching = vue.useModel(__props, "isSpeeching");
    const showFile = vue.ref(false);
    let originheight = 0;
    const actionComponents = vue.shallowRef({
      SenderButton: vue.h(senderButton_vue_vue_type_script_setup_true_lang.default, {
        onClick() {
          onSend();
        }
      }),
      LoadingButton: vue.h(loadingButton_vue_vue_type_script_setup_true_lang.default, {
        onClick() {
          onCancel();
        }
      }),
      SpeechButton: vue.h(speechButton_vue_vue_type_script_setup_true_lang.default, {
        onClick() {
          onSpeech();
        }
      }),
      SpeechLoadingButton: vue.h(speechLoadingButton_vue_vue_type_script_setup_true_lang.default, {
        onClick() {
          onStopSpeech();
        }
      }),
      LinkButton: vue.h(linkButton_vue_vue_type_script_setup_true_lang.default, {
        onClick() {
          onOpenFile();
        }
      })
    });
    const fileIconComponents = vue.shallowRef({
      xlsx: fileExcelIcon.default,
      ppt: filePptIcon.default,
      pdf: filePdfIcon.default,
      unknown: fileUnkownIcon.default,
      md: fileMarkdownIcon.default,
      json: fileTextIcon.default,
      text: fileTextIcon.default,
      word: fileWordIcon.default,
      zip: fileZipIcon.default
    });
    const isDisabled = vue.computed(() => {
      return !inputContent.value.trim();
    });
    const onCompositionStart = (evt) => {
      isComposing = true;
    };
    const onCompositionEnd = (evt) => {
      isComposing = false;
      inputContent.value = evt.target.value;
      vue.nextTick(() => {
        props.onChange && props.onChange(inputContent.value);
      });
    };
    const onInput = (evt) => {
      if (!isComposing) {
        inputContent.value = evt.target.value;
        vue.nextTick(() => {
          props.onChange && props.onChange(inputContent.value);
        });
      }
    };
    const onKeyPress = (evt) => {
      if (evt.shiftKey && (evt.key.toLowerCase() === "enter" || evt.keyCode == 13)) {
      } else if (evt.key.toLowerCase() === "enter" || evt.keyCode == 13) {
        evt.preventDefault();
        loading.value = true;
        emits("send", inputContent.value);
      }
    };
    const onClick = (evt) => {
      showFile.value = false;
      const { expand: { height: defaultExpandHeight = 200, enabled } } = props;
      if (enabled) {
        if (!isFocus.value) {
          const { height } = senderRef.value.getBoundingClientRect();
          const { height: contentHeight } = senderContentRef.value.getBoundingClientRect();
          senderContentRef.value.style.height = contentHeight + "px";
          originheight || (originheight = contentHeight);
          setTimeout(() => {
            isFocus.value = true;
            senderRef.value.style.cssText = `
          height : ${height}px;
          border: none;
          box-shadow: none;
          transition: height 0.3s;
        `;
            senderContentRef.value.style.cssText = `
          position: absolute;
          bottom: 0;
          width: 100%;
          height : ${defaultExpandHeight}px;
        `;
            textareaRef.value.style.cssText = `
          align-self: flex-start;
          overflow: auto;
          height: 100%;
        `;
          });
          textareaRef.value.focus();
        }
      }
    };
    const onBlur = () => {
      const { expand: { enabled } } = props;
      if (isSpeeching.value || !enabled) {
        return;
      }
      textareaRef.value.scrollTo({
        top: 0
      });
      setTimeout(() => {
        senderRef.value.style.border = "";
        senderRef.value.style.boxShadow = "";
        textareaRef.value.style.cssText = "";
        senderContentRef.value.style.height = originheight + "px";
        setTimeout(() => {
          isFocus.value = false;
          senderContentRef.value.style.cssText = "";
        }, 300);
      });
    };
    const onCancel = () => {
      loading.value = false;
      emits("cancel");
    };
    const onSend = () => {
      loading.value = true;
      emits("send", inputContent.value);
    };
    const onSpeech = async () => {
      isSpeeching.value = true;
      textareaRef.value.focus();
      speeching();
    };
    const speeching = () => {
      const { speech: { api, enabled, customSpeechToText } } = props;
      if (enabled) {
        if (api || customSpeechToText && typeof customSpeechToText === "function") {
          startSpeechToText();
        } else {
          defaultSpeechToText();
        }
      }
    };
    const startSpeechToText = async () => {
      recorder.start();
    };
    const defaultSpeechToText = () => {
      recognition.onresult = (event) => {
        let transcript = "";
        for (let i = event.resultIndex; i < event.results.length; i++) {
          transcript += event.results[i][0].transcript;
        }
        if (transcript) {
          inputContent.value = transcript;
        } else {
          stopSpeech();
        }
      };
      recognition.start();
    };
    const stopSpeech = () => {
      recognition.stop();
      isSpeeching.value = false;
    };
    const onStopSpeech = () => {
      const { speech: { api, customSpeechToText } } = props;
      textareaRef.value.blur();
      stopSpeech();
      if (api || customSpeechToText && typeof customSpeechToText === "function") {
        sendSpeechToText();
      }
    };
    const sendSpeechToText = async () => {
      const { speech: { api, getFormData, fieldName, customSpeechToText } } = props;
      const blob = getSpeechBlobData();
      if (api) {
        let formData = new FormData();
        if (getFormData && typeof getFormData === "function") {
          formData = getFormData(blob);
        } else {
          formData.append(fieldName, blob);
        }
        const result = await api(formData);
        if (result) {
          inputContent.value = result.message.text;
        }
      } else if (customSpeechToText && typeof customSpeechToText === "function") {
        const content = await customSpeechToText(blob);
        inputContent.value = content;
      }
    };
    const getSpeechBlobData = () => {
      const { speech: { blobType } } = props;
      let blob;
      switch (blobType) {
        case "wav":
          blob = recorder.getWAVBlob();
          break;
        case "pcm":
          blob = recorder.getPCMBlob();
          break;
        default:
          blob = recorder.getWAVBlob();
      }
      return blob;
    };
    const onOpenFile = () => {
      setTimeout(() => {
        showFile.value = !showFile.value;
      });
    };
    const getImageUrl = (file) => {
      const blob = URL.createObjectURL(file.file);
      return blob;
    };
    const onDeleteFile = (data) => {
      var _a, _b;
      if (props.uploadProps.fileList && props.uploadProps.fileList.length > 0) {
        props.uploadProps.fileList = (_b = (_a = props.uploadProps) == null ? void 0 : _a.fileList) == null ? void 0 : _b.filter((file) => file !== data);
      }
    };
    vue.onBeforeUnmount(() => {
      recognition.stop();
      recognition = null;
    });
    const setTextareaPosition = (target, direction) => {
      const len = target.value.length;
      const position = direction === "front" ? 0 : len;
      target.setSelectionRange(position, position);
      setTimeout(() => {
        target.setSelectionRange(position, position);
      }, 0);
    };
    __expose({
      blur() {
        if (textareaRef.value) {
          textareaRef.value.blur();
        }
      },
      focus() {
        if (textareaRef.value) {
          textareaRef.value.focus();
        }
      },
      focusInFirst() {
        if (textareaRef.value) {
          textareaRef.value.focus();
          setTextareaPosition(textareaRef.value, "front");
          textareaRef.value.scrollTo({
            top: 0
          });
        }
      },
      focusInLast() {
        if (textareaRef.value) {
          textareaRef.value.focus();
          setTextareaPosition(textareaRef.value, "end");
          textareaRef.value.scrollTo({
            top: textareaRef.value.scrollHeight
          });
        }
      },
      selectAll() {
        if (textareaRef.value) {
          textareaRef.value.focus();
          const len = textareaRef.value.value.length;
          textareaRef.value.setSelectionRange(0, len);
          setTimeout(() => {
            textareaRef.value.setSelectionRange(0, len);
          }, 0);
        }
      }
    });
    const isPicture = (type) => {
      const types = ["image/png", "image/gif", "image/jpeg", "image/jpg"];
      return types.includes(type);
    };
    const getFileComponent = (fileName) => {
      const arr = fileName.split(".");
      const type = arr[arr.length - 1];
      return fileIconComponents.value[type] || fileIconComponents.value.unknown;
    };
    const getFileSize = (fileSize) => {
      let result = fileSize;
      const units = ["B", "KB", "M", "G", "T"];
      let count = 0;
      const formatUnit = (size) => {
        if (size / 1024 >= 1) {
          if (count < units.length) {
            count++;
            result = Number((size / 1024).toFixed(2));
            formatUnit(result);
          }
        }
        return result + units[count];
      };
      return formatUnit(fileSize);
    };
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createElementBlock("div", {
        ref_key: "senderRef",
        ref: senderRef,
        class: "me-sender"
      }, [
        vue.createVNode(vue.Transition, { name: "slide" }, {
          default: vue.withCtx(() => [
            vue.withDirectives(vue.createElementVNode("div", {
              ref_key: "headerRef",
              ref: headerRef,
              class: "me-sender-header"
            }, [
              vue.createElementVNode("div", _hoisted_1, [
                vue.renderSlot(_ctx.$slots, "header", {}, () => {
                  var _a, _b, _c;
                  return [
                    _cache[3] || (_cache[3] = vue.createElementVNode("div", { class: "me-sender-header-title" }, "附件", -1)),
                    vue.withDirectives(vue.createElementVNode("div", _hoisted_2, [
                      (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList((_a = _ctx.uploadProps) == null ? void 0 : _a.fileList, (file, index2) => {
                        return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: index2 }, [
                          isPicture(file.file.type) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [
                            vue.createVNode(vue.unref(closeCircleFilledIcon.default), {
                              onClick: ($event) => onDeleteFile(file),
                              class: "close-icon"
                            }, null, 8, ["onClick"]),
                            vue.createVNode(vue.unref(antDesignVue.Image), {
                              src: getImageUrl(file)
                            }, null, 8, ["src"]),
                            file.percent !== 100 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4, vue.toDisplayString(file.percent) + "%", 1)) : vue.createCommentVNode("", true)
                          ])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_5, [
                            vue.createVNode(vue.unref(closeCircleFilledIcon.default), {
                              onClick: ($event) => onDeleteFile(file),
                              class: "close-icon"
                            }, null, 8, ["onClick"]),
                            vue.createElementVNode("div", _hoisted_6, [
                              vue.createElementVNode("div", _hoisted_7, [
                                (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(getFileComponent(file.file.name))))
                              ]),
                              vue.createElementVNode("div", _hoisted_8, [
                                vue.createElementVNode("div", _hoisted_9, vue.toDisplayString(file.file.name), 1),
                                vue.createElementVNode("div", _hoisted_10, vue.toDisplayString(getFileSize(file.file.size)), 1)
                              ])
                            ]),
                            file.percent !== 100 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_11, vue.toDisplayString(file.percent) + "%", 1)) : vue.createCommentVNode("", true)
                          ]))
                        ], 64);
                      }), 128)),
                      vue.createVNode(vue.unref(index.UploadFile), vue.mergeProps({
                        "file-list": _ctx.uploadProps.fileList,
                        "onUpdate:fileList": _cache[0] || (_cache[0] = ($event) => _ctx.uploadProps.fileList = $event)
                      }, vue.unref(lodashEs.omit)(_ctx.uploadProps, ["fileList"]), vue.toHandlers(_ctx.uploadEvents)), {
                        default: vue.withCtx(() => [
                          vue.createElementVNode("div", _hoisted_12, [
                            vue.createVNode(vue.unref(plusIcon.default), { class: "plus-icon" })
                          ])
                        ]),
                        _: 1
                      }, 16, ["file-list"])
                    ], 512), [
                      [vue.vShow, _ctx.uploadProps.fileList.length > 0]
                    ]),
                    vue.withDirectives(vue.createVNode(upload_vue_vue_type_script_setup_true_lang.default, {
                      "upload-props": _ctx.uploadProps,
                      "upload-events": _ctx.uploadEvents
                    }, null, 8, ["upload-props", "upload-events"]), [
                      [vue.vShow, ((_c = (_b = _ctx.uploadProps) == null ? void 0 : _b.fileList) == null ? void 0 : _c.length) === 0]
                    ])
                  ];
                })
              ])
            ], 512), [
              [vue.vShow, showFile.value]
            ])
          ]),
          _: 3
        }),
        vue.createElementVNode("div", {
          ref_key: "senderContentRef",
          ref: senderContentRef,
          onClick,
          class: vue.normalizeClass(["me-sender-content", { file: showFile.value, focus: isFocus.value }])
        }, [
          vue.createElementVNode("div", {
            onClick: _cache[1] || (_cache[1] = vue.withModifiers(() => {
            }, ["stop"])),
            class: "me-sender-prefix"
          }, [
            vue.renderSlot(_ctx.$slots, "prefix", vue.normalizeProps(vue.guardReactiveProps({ info: { LinkButton: actionComponents.value.LinkButton } })), () => [
              _ctx.upload ? (vue.openBlock(), vue.createBlock(linkButton_vue_vue_type_script_setup_true_lang.default, {
                key: 0,
                onClick: onOpenFile
              })) : vue.createCommentVNode("", true)
            ])
          ]),
          vue.createElementVNode("textarea", {
            ref_key: "textareaRef",
            ref: textareaRef,
            onBlur,
            placeholder: _ctx.placeholder,
            onKeypress: onKeyPress,
            onInput,
            onCompositionstart: onCompositionStart,
            onCompositionend: onCompositionEnd,
            value: inputContent.value,
            rows: _ctx.rows,
            class: "me-sender-text"
          }, null, 40, _hoisted_13),
          vue.createElementVNode("div", {
            class: "me-sender-actions",
            onClick: _cache[2] || (_cache[2] = vue.withModifiers(() => {
            }, ["stop"]))
          }, [
            vue.renderSlot(_ctx.$slots, "actions", vue.normalizeProps(vue.guardReactiveProps({ info: actionComponents.value })), () => [
              _ctx.speech.enabled ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
                isSpeeching.value ? (vue.openBlock(), vue.createBlock(speechLoadingButton_vue_vue_type_script_setup_true_lang.default, {
                  key: 0,
                  onClick: onStopSpeech
                })) : (vue.openBlock(), vue.createBlock(speechButton_vue_vue_type_script_setup_true_lang.default, {
                  key: 1,
                  onClick: onSpeech
                }))
              ], 64)) : vue.createCommentVNode("", true),
              loading.value ? (vue.openBlock(), vue.createBlock(loadingButton_vue_vue_type_script_setup_true_lang.default, {
                key: 1,
                onClick: onCancel
              })) : (vue.openBlock(), vue.createBlock(senderButton_vue_vue_type_script_setup_true_lang.default, {
                key: 2,
                onClick: onSend,
                disabled: isDisabled.value
              }, null, 8, ["disabled"]))
            ])
          ])
        ], 2)
      ], 512);
    };
  }
});
exports.default = _sfc_main;
//# sourceMappingURL=sender.vue2.cjs.map
